<!DOCTYPE html>
<html>

<head>
    <title>vue结合原生js实现拖动</title>
    <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <div class="ctn ctn1">
            <!-- draggable=true -->
            <div class="sub sub1" v-for="(site, index) in list1">
                <!-- @mousemove.prevent='mousemove(site, $event)' -->
                <div class="dragCtn fixed" @mousedown="mousedown(site, $event)" @mouseup='mouseup(site, $event)'>
                    {{ site.name }}
                </div>
            </div>
        </div>
        <div class="ctn ctn2">
            <div class="sub sub2" v-for="(site, index) in list2">
                <div class="dragCtn">
                    {{ index }} : {{ site.name }}
                </div>
            </div>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                list1: [{ name: '拖动我', index: 0 }],
                list2: [{ name: 'a', index: 0 }, { name: 'b', index: 1 }, { name: 'c', index: 2 }, { name: 'd', index: 3 }],
                vm: '',
                sb_bkx: 0,
                sb_bky: 0,
            },
            methods: {
                mousedown: function (site, event) {
                    var event = event || window.event;
                    var _target = event.target
                    var startx = event.clientX;
                    var starty = event.clientY;
                    var sb_bkx = startx - event.target.offsetLeft;
                    var sb_bky = starty - event.target.offsetTop;
                    var ww = document.documentElement.clientWidth;
                    var wh = window.innerHeight;
                    if (event.preventDefault) {
                        event.preventDefault();
                    } else {
                        event.returnValue = false;
                    };
                    document.onmousemove = function (ev) {
                        var event = ev || window.event;
                        var scrolltop = document.documentElement.scrollTop || document.body.scrollTop;
                        if (event.clientY < 0 || event.clientX < 0 || event.clientY > wh || event.clientX > ww) {
                            return false;
                        };
                        var endx = event.clientX - sb_bkx;
                        var endy = event.clientY - sb_bky;
                        _target.style.left = endx + 'px';
                        _target.style.top = endy + 'px';
                    }
                },
                mouseup: function (e) {
                    document.onmousemove = null;
                }
            }
        })
    </script>
    <style>
        .ctn {
            line-height: 50px;
            cursor: pointer;
            font-size: 20px;
            text-align: center;
            float: left;
        }

        .sub:hover {
            background: #e6dcdc;
            color: white;
            width: 100px;
        }

        .ctn1 {
            border: 1px solid green;
            width: 100px;
        }

        .ctn2 {
            border: 1px solid black;
            width: 100px;
            margin-left: 50px;
        }

        .fixed {
            width: 100px;
            height: 100px;
            position: fixed;
            background: red;
            left: 10px;
            top: 15px;
            cursor: move;
        }
    </style>
</body>

</html>